/*
 * BLLib.Collections.Generic.SortedList
 * Andy Tidball
 * 
 * Project: Black Lightning General Library
 * Copyright: GNU General Public License
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace BLLib.Collections.Generic {
	/// <summary>
	/// A list of values which are always stored in ascending sorted order.
	/// </summary>
	/// <typeparam name="T">The type of item to be stored in the list.</typeparam>
	public class SortedList<T> : List<T>
		where T : IComparable<T> {

		/// <summary>
		/// Adds a new value to the list in its sorted location.
		/// </summary>
		/// <param name="Value">The value to add to the list.</param>
		public new void Add(T Value) {
			// find the location we want to insert this at
			int i=0;
			for (i=0; i<base.Count; ++i) {
				T CurrentItem = base[i];
				if (CurrentItem.CompareTo(Value) >= 0) {
					break;
				}
			}

			// insert the value
			base.Insert(i, Value);
		}

		/// <summary>
		/// Adds a set of values from an enumerable collection to the list.
		/// </summary>
		/// <param name="Collection"></param>
		public new void AddRange(IEnumerable<T> Collection) {
			foreach (T Value in Collection) {
				Add(Value);
			}
		}

		/// <summary>
		/// Invalid operation.
		/// </summary>
		/// <param name="Index"></param>
		/// <param name="Value"></param>
		public new void Insert(int Index, T Value) {
			throw new InvalidOperationException("Cannot insert values arbitrarily into a sorted list.");
		}

		/// <summary>
		/// Invalid operation.
		/// </summary>
		/// <param name="Index"></param>
		/// <param name="Collection"></param>
		public new void InsertRange(int Index, IEnumerable<T> Collection) {
			throw new InvalidOperationException("Cannot insert values arbitrarily into a sorted list.");
		}

		/// <summary>
		/// Returns a copy of this list which is in reverse order.
		/// </summary>
		/// <returns>A list which contains the same elements as this one but in reverse.</returns>
		public new List<T> Reverse() {
			List<T> NewList = new List<T>(this);
			NewList.Reverse();
			return NewList;
		}
		
		/// <summary>
		/// Returns a copy of this list with a sub-set of it reversed.
		/// </summary>
		/// <returns>A list which contains the same elements as this one but with a sub-set in reverse.</returns>
		public new List<T> Reverse(int Index, int Count) {
			List<T> NewList = new List<T>(this);
			NewList.Reverse(Index, Count);
			return NewList;
		}

		/// <summary>
		/// Does nothing, the list is sorted by default.
		/// </summary>
		public new void Sort() {
			return;
		}

		/// <summary>
		/// Invalid operation.
		/// </summary>
		/// <param name="Comparison"></param>
		public new void Sort(Comparison<T> Comparison) {
			throw new InvalidOperationException("Cannot sort a sorted list in any other than default order.");
		}
		
		/// <summary>
		/// Invalid operation.
		/// </summary>
		/// <param name="Comparison"></param>
		public new void Sort(IComparer<T> Comparison) {
			throw new InvalidOperationException("Cannot sort a sorted list in any other than default order.");
		}
		
		/// <summary>
		/// Invalid operation.
		/// </summary>
		/// <param name="Index"></param>
		/// <param name="Count"></param>
		/// <param name="Comparison"></param>
		public new void Sort(int Index, int Count, IComparer<T> Comparison) {
			throw new InvalidOperationException("Cannot sort a sorted list in any other than default order.");
		}
	}
}
